package com.wg.elasticsearch.druid;

import com.alibaba.druid.pool.DruidDataSource;
import io.shardingjdbc.core.api.MasterSlaveDataSourceFactory;
import io.shardingjdbc.core.api.config.MasterSlaveRuleConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableConfigurationProperties({DruidMasterProperties.class, DruidSlave1Properties.class})
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
public class DruidAutoConfiguration {

    @Autowired
    private DruidMasterProperties masterProperties;

    @Autowired
    private DruidSlave1Properties slave1Properties;

    @Bean
    @Primary
    public DataSource dataSource() {
        DruidDataSource masterDataSource = this.MasterDataSource();
        DruidDataSource slave1DataSource = this.Slave1DataSource();
        Map<String, DataSource> dataSourceMap = new HashMap<>(2);
        dataSourceMap.put("masterDataSource", masterDataSource);
        dataSourceMap.put("slave1DataSource", slave1DataSource);
        MasterSlaveRuleConfiguration dataRoleConfig = this.dataRoleConfig();
        Map<String, Object> configMap = new HashMap<>(2);
        DataSource dataSource;
        try {
            dataSource = MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, dataRoleConfig, configMap);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return dataSource;
    }

    private MasterSlaveRuleConfiguration dataRoleConfig() {
        MasterSlaveRuleConfiguration dataRoleConfig = new MasterSlaveRuleConfiguration();
        dataRoleConfig.setName("master_slave");
        dataRoleConfig.setMasterDataSourceName("masterDataSource");
        dataRoleConfig.getSlaveDataSourceNames().add("slave1DataSource");
        return dataRoleConfig;
    }

    private DruidDataSource MasterDataSource() {
        return this.createDataSource(masterProperties);
    }

    private DruidDataSource Slave1DataSource() {
        return this.createDataSource(slave1Properties);
    }

    private DruidDataSource createDataSource(DruidProperties properties) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(properties.getUrl());
        dataSource.setUsername(properties.getUsername());
        dataSource.setPassword(properties.getPassword());
        if (properties.getInitialSize() > 0) {
            dataSource.setInitialSize(properties.getInitialSize());
        }
        if (properties.getMinIdle() > 0) {
            dataSource.setMinIdle(properties.getMinIdle());
        }
        if (properties.getMaxActive() > 0) {
            dataSource.setMaxActive(properties.getMaxActive());
        }
        if (properties.getMaxWait() > 0) {
            dataSource.setMaxWait(properties.getMaxWait());
        }
        dataSource.setTestOnBorrow(properties.isTestOnBorrow());
        dataSource.setTestOnReturn(properties.isTestOnReturn());
        dataSource.setTestWhileIdle(properties.isTestWhileIdle());
        try {
            dataSource.init();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return dataSource;
    }
}
